#coding:utf-8


from twisted.internet import reactor, defer, threads
from twisted.internet.protocol import Protocol, Factory, DatagramProtocol

import sys, os, time
import vehicle
from datamethod import *
import buss
import pickle
import datetime
import report

class BasePlayer:
    """Only tell you Player has also dad."""


class Player(BasePlayer):
    vehicleTable = {}
    connectorTable = {}
    def __init__(self):
        import buss
        report.info('********************player started*******************')
        
    def __del__(self):
        report.info('********************player closed*******************')
      
    def connectionCreated(self, tel, connector):
        """ Call it when tcp server get logon request."""
        assert isinstance(tel, str)
        _preConnector = self.getConnector(tel)
        if connector != _preConnector:
            
            if _preConnector: _preConnector.loseConnection()
            self.updateConnector(tel, connector)
            self.callVehicle(tel, 'connectionCreated')
            
    def connectionLost(self, tel, connector):
        """ If connector is lost, call it."""
        _curConnector = self.getConnector(tel)
        if connector == _curConnector:
            self.removeConnector(tel)
            self.callVehicle(tel, 'connectionLost')
            
    def setVehicleData(self, tel, testList):
        """ Set test data. if vehicle has yet data, then update and
        restart play test.
        """
        vehicleData = self.getVehicle(tel)
        if not vehicleData:
            vehicleData = vehicle.VehicleData(self, tel)
            self.updateVehicle(tel, vehicleData)
        vehicleData.setTestList(testList)
        
    def getVehicle(self, tel):
        """ wrapper method of vehicle table."""
        return self.vehicleTable.get(tel, None)
    
    def updateVehicle(self, tel, vehicleData):
        """ see self.getVehicle method"""
        self.vehicleTable.update({tel:vehicleData})
        
    def removeVehicle(self, tel):
        """ see self.getVehicle"""
        self.vehicleTable.pop(tel)
        
    def callVehicle(self, tel, called, *args, **kw):
        """ speed way of call vehicle method. if vehicle is None,
        then nothing is happened.
        """
        v = self.getVehicle(tel)
        if not v:
            v = vehicle.VehicleData(self, tel)
            self.updateVehicle(tel, v)
        callable = eval("v.%s"%called)
        return callable(*args, **kw)
    
    def getConnector(self, tel):
        """ wrapper method of connector table."""
        return self.connectorTable.get(tel, None)
    
    def updateConnector(self, tel, connector):
        """ see self.getConnector"""
        self.connectorTable.update({tel:connector})
        
    def removeConnector(self, tel):
        """ see self.getConnector"""
        self.connectorTable.pop(tel)
        
    def callConnector(self, tel, callback, *args, **kw):
        """ speed way of call connector method. if connector is None,
        then nothing is happened.
        See self.callVehicle(tel, callback, *args, **kw).
        """
        c = self.getConnector(tel)
        if c:
            callable = eval("c.%s"%callback)
            return callable(*args, **kw)
            
    def bussDataReceived(self, tel, data):
        vehicle = self.vehicleTable.get(tel)
        if vehicle:vehicle.feedData(data)
        
    def startTest(self, tel):
        """ start test of vehicle. return True if success, else False.
        """
        vehicleData = self.getVehicle(tel)
        if vehicleData:
            vehicleData.startTest()
            return True
        return False
        
    def stopTest(self, tel):
        vehicleData = self.getVehicle(tel)
        if vehicleData:
            vehicleData.closeTest()
            return True
        return False
            
    def requestVehicleState(self, tel):
        if hasattr(self, 'user'):
            if self.getConnector(tel):
                self.user.sendVehicleState(tel, True)
            else:
                self.user.sendVehicleState(tel, False)
                
    def requestAllVehicleState(self):
        if hasattr(self, 'user'):
            for tel in self.connectorTable.keys():
                self.user.sendVehicleState(tel, True)
                
    def requestTestProcess(self, tel):
        if hasattr(self, 'user'):
            v = self.getVehicle(tel)
            if v:
                self.user.sendTestProcess(tel, v.getTestTime(), v.getTotalTestTime())
            
    def setReportPath(self, tel, pathname):
        vehicleData = self.getVehicle(tel)
        if not vehicleData:
            vehicleData = vehicle.VehicleData(self, tel)
            self.updateVehicle(tel, vehicleData)
        #vehicleData.setReportPath(pathname)
        
    def terminate(self):
        reactor.stop()
        
    def notifyTestProcess(self, tel):
        pass
        
if __name__ == '__main__':
    player = Player()